﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Windows.Forms;

namespace Bluetooth_Fan
{

    /// <summary>
    /// 蓝牙风扇 接口应答
    /// </summary>
    class Bluetooth_Fan_Protocol
    {
        public enum SET_MOTO_STATUS
        {
            MOTO_STOP = 0X00,         //停止
            MOTO_RUN = 0X01,          //正转
            MOTO_Invert = 0X02,       //反转
        }

        public enum SYS_USER_COMM_Enum      //命令集 枚举
        {
            /// <summary>
            ///固件升级
            /// </summary>
            SET_SYS_Updata = 0,
            /// <summary>
            /// 设置电机分段转速
            /// </summary>
            SET_MOTO_PWM_Section_COMM = 0X01,
            /// <summary>
            /// 设置电机PWM 值
            /// </summary>
            SET_MOTO_PWM_COMM = 0X02,
            /// <summary>
            /// 设置电机定时功能
            /// </summary>
            SET_MOTO_RUN_TIME_COMM = 0X03,
            /// <summary>
            /// 设置电机正反转
            /// </summary>
            SET_MOTO_Direction_COMM = 0X04,

            //应答部分  上位机发送过来的应答   用于判断是否与上位机连接--------------
            /// <summary>
            /// 上报电机定时功能计时时间     应答
            /// </summary>
            Rep_MOTO_RUN_TIME = 0XF2,
            /// <summary>
            /// 上报设备运行状态      应答
            /// </summary>
            Rep_SYS_RUN_STA = 0XF1,
            /// <summary>
            /// 上报设备运行参数      应答
            /// </summary>
            Rep_SYS_State = 0XF3,
            /// <summary>
            /// 上报及请求固件版本
            /// </summary>
            Rep_SYS_VER = 0XFF,
        }

        #region
        public const byte Protocol_Head0 = 0XAA;        //数据头 0
        public const byte Protocol_Head1 = 0X55;    //数据头 1
        #endregion

        public struct Protocol_Data
        {
            public Byte HEAD0;
            public Byte HEAD1;       //命令头
            public Byte MOTO_OBJ;    //电机对象
            public SYS_USER_COMM_Enum USER_CMM;    //用户命令 
            public Byte Data_Len;    //数据段长度
            public Byte[] data;        //数据段
            public Byte CRC;         //CRC
        };


        //底层--------------------------------------------------------------
        //求CRC值
        public Byte Return_CRC_DATA(Protocol_Data Protocol_data)
        {
            Byte CRC_Data = 0;

            CRC_Data += Protocol_data.HEAD0;
            CRC_Data += Protocol_data.HEAD1;
            CRC_Data += Protocol_data.MOTO_OBJ;
            CRC_Data += (byte)Protocol_data.USER_CMM;
            CRC_Data += Protocol_data.Data_Len;
            for (int i = 0; i < Protocol_data.Data_Len; i++)
            {
                CRC_Data += Protocol_data.data[i];
            }
            CRC_Data = (Byte)(0 - CRC_Data);  //求CRC
            return CRC_Data;
        }

        /// <summary>
        /// 需要发送的接口数据
        /// </summary>
        public static List<Protocol_Data> Send_Protocol_data_List = new List<Protocol_Data>();

        /// <summary>
        /// 需要发送的接口数据类加入List
        /// </summary>
        /// <param name="Protocol_data"></param>
        public void Send_Protocol_data(Protocol_Data Protocol_data)
        {
            Send_Protocol_data_List.Add(Protocol_data);  //添加到List
        }

        /// <summary>
        /// 发送List中的数据类对象
        /// </summary>
        /// <param name="SerialPort">发送数据的串口</param>
        /// <returns></returns>
        public static void Send_Protocol_List_data(SerialPort SerialPort)
        {
            if (Send_Protocol_data_List.Count > 0)
            {
                Protocol_Data Protocol_data = Send_Protocol_data_List[0];   //读取
                Send_Protocol_data_List.RemoveAt(0);   //删除
                try
                {
                    byte[] send_data = new byte[6 + Protocol_data.Data_Len]; //声明发送缓存
                    send_data[0] = Protocol_data.HEAD0;
                    send_data[1] = Protocol_data.HEAD1;
                    send_data[2] = Protocol_data.MOTO_OBJ;
                    send_data[3] = (byte)Protocol_data.USER_CMM;
                    send_data[4] = Protocol_data.Data_Len;
                    for (int i = 0; i < Protocol_data.Data_Len; i++)
                    {
                        send_data[5 + i] = Protocol_data.data[i];
                    }
                    send_data[send_data.Length - 1] = Protocol_data.CRC;
                    SerialPort.Write(send_data, 0, send_data.Length);    //发送
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        //----------------------------------------------------------------------------
        //电机控制命令1   控制电机转速档
        public void SET_MOTO_Speed_Grade(Byte MOTO_OBJ, SET_MOTO_STATUS SET_Status, Byte grade)
        {
            Protocol_Data Protocol_data = new Protocol_Data();
            Protocol_data.HEAD0 = Protocol_Head0;
            Protocol_data.HEAD1 = Protocol_Head1;
            Protocol_data.MOTO_OBJ = MOTO_OBJ;
            Protocol_data.USER_CMM = SYS_USER_COMM_Enum.SET_MOTO_PWM_Section_COMM;
            Protocol_data.Data_Len = 2;
            Protocol_data.data = new Byte[Protocol_data.Data_Len];
            Protocol_data.data[0] = (byte)SET_Status;
            Protocol_data.data[1] = grade;
            Protocol_data.CRC = Return_CRC_DATA(Protocol_data);
            Send_Protocol_data(Protocol_data);
        }

        //电机控制命令2  控制电机转速无极值
        public void SET_MOTO_PWM_Val(Byte MOTO_OBJ, SET_MOTO_STATUS SET_Status, UInt16 pwm_val)
        {
            Protocol_Data Protocol_data = new Protocol_Data();
            Protocol_data.HEAD0 = Protocol_Head0;
            Protocol_data.HEAD1 = Protocol_Head1;
            Protocol_data.MOTO_OBJ = MOTO_OBJ;
            Protocol_data.USER_CMM = SYS_USER_COMM_Enum.SET_MOTO_PWM_COMM;
            Protocol_data.Data_Len = 3;  //数据长度
            Protocol_data.data = new Byte[Protocol_data.Data_Len];
            Protocol_data.data[0] = (byte)SET_Status;
            Protocol_data.data[1] = (byte)(pwm_val / 256);
            Protocol_data.data[2] = (byte)(pwm_val % 256);
            Protocol_data.CRC = Return_CRC_DATA(Protocol_data);
            Send_Protocol_data(Protocol_data);  //发送
        }

        //电机控制命令3  设置电机工作时间
        public void SET_MOTO_RUN_Tim(Byte MOTO_OBJ, UInt16 run_time)
        {
            Protocol_Data Protocol_data = new Protocol_Data();
            Protocol_data.HEAD0 = Protocol_Head0;
            Protocol_data.HEAD1 = Protocol_Head1;
            Protocol_data.MOTO_OBJ = MOTO_OBJ;
            Protocol_data.USER_CMM = SYS_USER_COMM_Enum.SET_MOTO_RUN_TIME_COMM;
            Protocol_data.Data_Len = 2;  //数据长度
            Protocol_data.data = new Byte[Protocol_data.Data_Len];
            Protocol_data.data[0] = (byte)(run_time / 256);
            Protocol_data.data[1] = (byte)(run_time % 256);
            Protocol_data.CRC = Return_CRC_DATA(Protocol_data);
            Send_Protocol_data(Protocol_data);  //发送
        }

        //电机控制命令4  设置电机正反转 及停止
        public void SET_MOTO_Direction(Byte MOTO_OBJ, SET_MOTO_STATUS SET_Status)
        {
            Protocol_Data Protocol_data = new Protocol_Data();
            Protocol_data.HEAD0 = Protocol_Head0;
            Protocol_data.HEAD1 = Protocol_Head1;
            Protocol_data.MOTO_OBJ = MOTO_OBJ;
            Protocol_data.USER_CMM = SYS_USER_COMM_Enum.SET_MOTO_Direction_COMM;
            Protocol_data.Data_Len = 1;  //数据长度
            Protocol_data.data = new Byte[Protocol_data.Data_Len];
            Protocol_data.data[0] = (byte)SET_Status;
            Protocol_data.CRC = Return_CRC_DATA(Protocol_data);
            Send_Protocol_data(Protocol_data);  //发送
        }
    }
}
